package com.acme.bankapp;

import java.io.IOException;
import java.util.Scanner;

import com.acme.domain.account.Account;
import com.acme.domain.account.CheckingAccount;
import com.acme.domain.account.SavingAccount;
import com.acme.domain.client.Bank;
import com.acme.domain.client.Client;
import com.acme.domain.client.Gender;
import com.acme.exceptions.BankException;
import com.acme.service.bank.BankReportPresentationService;
import com.acme.service.bank.BankReportService;
import com.acme.service.bank.impl.BankReportServiceImpl;
import com.acme.service.bank.impl.BankServiceImpl;
import com.acme.service.bank.impl.ConsoleBankReportPresentationService;

public class BankApplication {
	private static BankReportPresentationService bankReportPresentationService;

	private static BankReportService bankReportService;

	private static BankServiceImpl bankService;

	public static void main(final String[] args) throws IOException,
			BankException {

		initServices();

		Bank bank = createInMemoryBank();

		for (int i = 0; i < args.length; i++) {
			if (args[i].equals("-statistics")) {
				System.out
						.println("Enter command:\n\tNBC - print number of bank customers;");
				System.out.println("\tNA - print number of opened accounts;");
				System.out
						.println("\tASS - print accounts sorted by amount value;");
				System.out.println("\tBC - print total bank credit;");
				System.out
						.println("\tMAP - print map of clients and their accounts;");
				System.out.println("\tEXIT - exit program.");

				Scanner in = new Scanner(System.in);
				while (true) {
					String enter = in.next();

					switch (enter) {
					case "NBC":
						bankReportPresentationService
								.printNumberOfClients(bank);
						break;
					case "NA":
						bankReportPresentationService
								.printNumberOfOpenedAccounts(bank);
						break;
					case "ASB":
						bankReportPresentationService
								.printAccountsSortedBySum(bank);
						break;
					case "BC":
						bankReportPresentationService.printBankCredit(bank);
						break;
					case "MAP":
						bankReportPresentationService
								.printCustomerAccount(bank);
						break;
					case "EXIT":
						break;
					default:
						System.out.println("Invalid command.");
						break;
					}
					if (enter.equals("EXIT")) {
						break;
					}
				}
			}
		}
		if (args.length == 0) {
			printTheBank(bank);
		}
	}

	private static void initServices() {
		bankService = new BankServiceImpl();
		bankReportService = new BankReportServiceImpl();
		bankReportPresentationService = new ConsoleBankReportPresentationService();
		bankReportPresentationService.setBankReportService(bankReportService);
	}

	private static void printTheBank(final Bank bank) {
		bankReportPresentationService.printAccountsSortedBySum(bank);
		bankReportPresentationService.printBankCredit(bank);
		bankReportPresentationService.printNumberOfClients(bank);
		bankReportPresentationService.printNumberOfOpenedAccounts(bank);
		bankReportPresentationService.printCustomerAccount(bank);
	}

	private static Bank createInMemoryBank() throws BankException {
		Bank bank = new Bank();
		Client client1 = bankService.addClient(bank, "John", Gender.MALE);
		Account account1 = new SavingAccount(1, 100);
		Account account2 = new CheckingAccount(2, 100, 0);
		client1.addAccount(account1);
		client1.addAccount(account2);

		Client client2 = bankService.addClient(bank, "Miranda", Gender.FEMALE);
		Account account3 = new SavingAccount(3, 50);
		Account account4 = new CheckingAccount(4, 75, 20);
		client2.addAccount(account3);
		client2.addAccount(account4);

		Client client3 = bankService.addClient(bank, "Lisa", Gender.FEMALE);
		Account account5 = new SavingAccount(5, 100);
		Account account6 = new CheckingAccount(6, 90, 30);
		client3.addAccount(account5);
		client3.addAccount(account6);

		Client client4 = bankService.addClient(bank, "Valdemar", Gender.MALE);
		Account account7 = new SavingAccount(7, 400);
		Account account8 = new CheckingAccount(8, 50, 90);
		client4.addAccount(account7);
		client4.addAccount(account8);

		account1.deposit(100);

		account4.withdraw(80);

		return bank;
	}
}
